package example;

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

public class MyBlockingQueue {
    private int[] items = new int[1000];
    private volatile int tail;
    private volatile int usedSize;
    private volatile int head;

    /**
     * 入队
     * @param elem
     */
    private void put(int elem) throws InterruptedException {
        synchronized (this) {
            while (usedSize >= items.length){
                // return;
                this.wait();
            }
            items[tail] = elem;
            tail++;
            if (tail >= items.length){
                tail = 0;
            }
            usedSize++;
            this.notify();
        }
    }

    /**
     * 出队列
     * @return
     */
    private Integer take() throws InterruptedException {
        synchronized (this) {
            while (usedSize == 0){
                //return null;
                this.wait();
            }
            int ret = items[head];
            head++;
            if (head >= items.length){
                head = 0;
            }
            usedSize--;
            this.notify();
            return ret;
        }
    }

    public static void main(String[] args) throws InterruptedException {
//        BlockingDeque<Integer> blockingDeque = new LinkedBlockingDeque<>();
//        blockingDeque.put(1);
//        blockingDeque.put(2);
//        blockingDeque.put(3);
//        int ret = blockingDeque.take();
//        System.out.println(ret);
//        ret = blockingDeque.take();
//        System.out.println(ret);
//        ret = blockingDeque.take();
//        System.out.println(ret);
//        blockingDeque.take();

        MyBlockingQueue myBlockingQueue = new MyBlockingQueue();
        myBlockingQueue.put(1);
        System.out.println(myBlockingQueue.take());
        myBlockingQueue.take();
    }
}
